package com.iwdnb.gkgz.common.utils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import cn.hutool.core.date.DateUtil;
import com.iwdnb.bmnf.common.utils.BeanConvertUtils;
import com.iwdnb.bmnf.common.utils.BooleanUtils;
import com.iwdnb.bmnf.common.utils.HttpClientUtils;
import com.iwdnb.gkgz.common.model.dto.StockDayData;
import com.iwdnb.gkgz.common.quota.Macd;
import com.iwdnb.gkgz.common.quota.Macd.MacdData;
import com.iwdnb.gkgz.common.quota.Macd.MacdRegion;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import static com.iwdnb.gkgz.common.utils.BigDecimalUtils.eight;

@Slf4j
public class StockFenshiUtils {
    private static final String FENSHI_URL = "https://web.ifzq.gtimg.cn/appstock/app/minute/query?code=%s";

    public static List<StockDayData> getFenshiList(String code) {
        Date d = new Date();
        String date = DateUtil.formatDate(new Date());
        String response = HttpClientUtils.get(String.format(FENSHI_URL, code));
        JSONObject jsonObject = JSON.parseObject(response);
        jsonObject = jsonObject.getJSONObject("data").getJSONObject(code).getJSONObject("data");
        List<String> list = jsonObject.getJSONArray("data").toJavaList(String.class);
        BigDecimal openPrice = null;
        BigDecimal maxPrice = null;
        BigDecimal minPrice = null;
        int tradeNum = 0;
        int temp = 0;
        List<StockDayData> stockDayDataList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            StockDayData data = buildStockData(s, code, date);
            if (i == 0) {
                openPrice = data.getClosePrice();
                maxPrice = data.getClosePrice();
                minPrice = data.getClosePrice();
            } else {
                if (BigDecimalUtils.isGt(data.getClosePrice(), maxPrice)) {
                    maxPrice = data.getClosePrice();
                } else if (BigDecimalUtils.isLt(data.getClosePrice(), minPrice)) {
                    minPrice = data.getClosePrice();
                }
            }
            data.setOpenPrice(openPrice);
            data.setMaxPrice(maxPrice);
            data.setMinPrice(minPrice);
            //计算每分钟的实际成交量
            temp = data.getTradeNum();
            data.setTradeNum(temp - tradeNum);
            tradeNum = temp;
            stockDayDataList.add(data);
        }
        log.info("{}-getFenshiList finished,size:{}.", code, stockDayDataList.size());
        return stockDayDataList;
    }

    private static StockDayData buildStockData(String s, String code, String date) {
        String[] array = s.split(" ");
        String time = array[0];
        String hour = time.substring(0, 2);
        String minute = time.substring(2, 4);
        BigDecimal price = BigDecimalUtils.of(array[1]);
        Integer tradeNum = Integer.valueOf(array[2]);
        StockDayData data = new StockDayData();
        data.setCode(code);
        data.setDate(date);
        time = date + " " + hour + ":" + minute + ":00";
        data.setDatetime(time);
        data.setClosePrice(price);
        data.setTradeNum(tradeNum);
        return data;
    }

    public static StockDayData getRiseUpData(List<StockDayData> stockDayDataList, BigDecimal beforeClosePrice) {
        if (CollectionUtils.isEmpty(stockDayDataList) || stockDayDataList.size() < 5) {
            return null;
        }
        //开盘直线拉升股票处理
        boolean isOpenRiseUp = isOpenRiseUp(stockDayDataList, beforeClosePrice);
        if (isOpenRiseUp) {
            return null;
        }
        //开盘后15分钟处理
        if (stockDayDataList.size() >= 16) {
            //10分钟5个点以上
            StockDayData data = findRiseUpData(stockDayDataList, BigDecimalUtils.five, 10, beforeClosePrice);
            if (Objects.nonNull(data)) {
                return data;
            }
            //5分钟3个点以上
            return findRiseUpData(stockDayDataList, BigDecimalUtils.threePontFive, 5, beforeClosePrice);
        }
        return null;
    }

    private static boolean isOpenRiseUp(List<StockDayData> stockDayDataList, BigDecimal beforeClosePrice) {
        if (stockDayDataList.size() >= 16) {
            stockDayDataList = stockDayDataList.subList(0, 16);
        }
        BigDecimal openBeforeCloseRate = BigDecimalUtils.subStractAndDividePrecent(
            stockDayDataList.get(0).getOpenPrice(),
            beforeClosePrice);
        if (BigDecimalUtils.isGt(openBeforeCloseRate, BigDecimalUtils.seven)) {
            return true;
        }
        StockDayData maxData = StockUtils.getMaxPriceData(stockDayDataList);
        StockDayData minData = StockUtils.getMinPriceData(stockDayDataList);
        //开盘直接冲高7个点，参照sz002593-20241211
        BigDecimal openRate = BigDecimalUtils.subStractAndDividePrecent(maxData.getClosePrice(),
            maxData.getOpenPrice());
        if (BigDecimalUtils.isGt(openRate, BigDecimalUtils.seven)) {
            return true;
        }
        //通用拉升情况处理
        if (DateUtils.after(maxData.getDatetime(), minData.getDatetime())) {
            BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(maxData.getClosePrice(),
                minData.getClosePrice());
            int maxMinite = DateUtil.minute(DateUtil.parseDateTime(maxData.getDatetime()));
            int minMinite = DateUtil.minute(DateUtil.parseDateTime(minData.getDatetime()));
            int time = maxMinite - minMinite;
            //8分钟内拉升超过7个点
            if (time <= 8 && BigDecimalUtils.isGe(rate, BigDecimalUtils.seven)) {
                return true;
            }
            //5分钟内拉5个点
            if (time <= 5 && BigDecimalUtils.isGt(rate, BigDecimalUtils.five)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 开盘直线拉升的股票走势(概率拉板)
     *
     * @param fenshiList
     * @param beforeClosePrice
     * @return
     */
    private static StockDayData findOpenRiseUpLimitData(List<StockDayData> fenshiList, BigDecimal beforeClosePrice) {
        //后续跌破均价线1.5点就是卖出信号
        List<StockDayData> afterList = fenshiList.subList(4, fenshiList.size());
        for (StockDayData data : afterList) {
            BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(data.getClosePrice(), beforeClosePrice);
            if (BigDecimalUtils.isGe(rate, BigDecimalUtils.ninePointSix)) {
                return null;
            }
            BigDecimal avgRate = BigDecimalUtils.subStractAndDividePrecent(data.getAvgPrice(), data.getClosePrice());
            if (BigDecimalUtils.isGe(avgRate, BigDecimalUtils.onePointFive)) {
                return data;
            }
        }
        return null;
    }

    private static StockDayData findRiseUpData(List<StockDayData> stockDayDataList, BigDecimal rateLimit, int sizeLimit,
        BigDecimal beforeClosePrice) {
        List<StockDayData> fenshiList = null;
        int size = stockDayDataList.size();
        if (size < sizeLimit) {
            sizeLimit = size;
        }
        StockDayData data = null;
        StockDayData mactchData = null;
        int index = 0;
        for (int i = 0; i < size; i++) {
            index = i + sizeLimit - 1 < size ? i + sizeLimit - 1 : size - 1;
            data = stockDayDataList.get(index);
            //出现涨停板,直接忽略
            BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(data.getClosePrice(), beforeClosePrice);
            if (BigDecimalUtils.isGe(rate, BigDecimalUtils.ninePointSix)) {
                return null;
            }
            fenshiList = stockDayDataList.subList(i, index);
            if (CollectionUtils.isEmpty(fenshiList)) {
                break;
            }
            StockDayData minData = StockUtils.getMinPriceData(fenshiList);
            StockDayData maxData = StockUtils.getMaxPriceData(fenshiList);
            if (BigDecimalUtils.isGt(maxData.getClosePrice(), data.getClosePrice())) {
                data = maxData;
            }
            Date minTime = DateUtil.parseDateTime(minData.getDatetime());
            Date time = DateUtil.parseDateTime(data.getDatetime());
            //时间不能在最小值之前
            if (time.before(minTime)) {
                continue;
            }
            //股价短期飙升3个点以上
            rate = BigDecimalUtils.subStractAndDividePrecent(data.getClosePrice(), minData.getClosePrice());
            if (BigDecimalUtils.isLt(rate, rateLimit)) {
                continue;
            }
            //涨幅在昨日收盘价1.5以上
            BigDecimal beforeCloseRate = BigDecimalUtils.subStractAndDividePrecent(data.getClosePrice(),
                beforeClosePrice);
            if (BigDecimalUtils.isLt(beforeCloseRate, BigDecimalUtils.onePointFive)) {
                continue;
            }
            ////量比大于1.25
            //BigDecimal volume = StockUtils.getStockQuota(data, VolumeRatioIndicator.QUOTA_NAME);
            //if (BigDecimalUtils.isLt(volume, new BigDecimal(1.1))) {
            //    continue;
            //}
            //macd值为本次上涨最高点活与本次最高点10%之内
            MacdData macd = data.getMacd();
            BigDecimal bar = fenshiList.get(0).getMacd().getBar();
            StockDayData highMacdData = fenshiList.get(0);
            for (StockDayData fenshiData : fenshiList) {
                if (BigDecimalUtils.isGt(fenshiData.getMacd().getBar(), bar)) {
                    highMacdData = fenshiData;
                    bar = fenshiData.getMacd().getBar();
                    break;
                }
            }
            BigDecimal macdBar = BigDecimalUtils.eq(macd.getBar(), BigDecimal.ZERO) ? new BigDecimal(-0.0001)
                : macd.getBar();
            //BigDecimal macdRate = BigDecimalUtils.subStractAndDividePrecent(highMacdData.getMacd().getBar(),
            //    macdBar);
            //if (BigDecimalUtils.isGt(macdRate, ten)) {
            //    continue;
            //}
            //后一分钟的macd柱缩短8%
            if (i < stockDayDataList.size()) {
                StockDayData afterData = getNextMinuteStockDayData(data, stockDayDataList);
                MacdData afterMacd = afterData.getMacd();
                BigDecimal afterMacdBar = BigDecimalUtils.eq(afterMacd.getBar(), BigDecimal.ZERO) ? new BigDecimal(
                    -0.0001) : afterMacd.getBar();
                BigDecimal macdRate = BigDecimalUtils.subStractAndDividePrecent(macdBar, afterMacdBar);
                if (BigDecimalUtils.isGe(macdRate, eight)) {
                    mactchData = BeanConvertUtils.convert(afterData, StockDayData.class);
                    mactchData.setFenshiRate(rate);
                    break;
                } else {
                    afterData = getNextMinuteStockDayData(afterData, stockDayDataList);
                    afterMacd = afterData.getMacd();
                    afterMacdBar = BigDecimalUtils.eq(afterMacd.getBar(), BigDecimal.ZERO) ? new BigDecimal(-0.0001)
                        : afterMacd.getBar();
                    macdRate = BigDecimalUtils.subStractAndDividePrecent(macdBar, afterMacdBar);
                    if (BigDecimalUtils.isGe(macdRate, eight)) {
                        mactchData = BeanConvertUtils.convert(afterData, StockDayData.class);
                        mactchData.setFenshiRate(rate);
                        break;
                    }
                    //忽略macd量柱缩小，但是价格还在上涨的票
                    //if (BigDecimalUtils.isGt(highMacdData.getClosePrice(), data.getClosePrice())) {
                    //    mactchData = BeanConvertUtils.convert(afterData, StockDayData.class);
                    //    mactchData.setFenshiRate(rate);
                    //}

                }

            }
        }
        if (Objects.isNull(mactchData)) {
            return null;
        }

        //最高价到过9个点的忽略
        BigDecimal maxRate = BigDecimalUtils.subStractAndDividePrecent(mactchData.getMaxPrice(), beforeClosePrice);
        if (BigDecimalUtils.isGe(maxRate, BigDecimalUtils.nine)) {
            return null;
        }
        //涨幅小于1.5的忽略
        BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(mactchData.getClosePrice(), beforeClosePrice);
        if (BigDecimalUtils.isLe(rate, BigDecimalUtils.onePointFive)) {
            return null;
        }
        String twoHourTime = mactchData.getDate() + " 14:00:00";
        //信号在2点以后忽略,后面1小时亏不了多少
        if (DateUtils.afterOrEquals(mactchData.getDatetime(), twoHourTime)) {
            return null;
        }
        //忽略信号在9.45以前
        String nineHourFourtyTime = mactchData.getDate() + " 09:45:00";
        if (DateUtils.beforeOrEquals(mactchData.getDatetime(), nineHourFourtyTime)) {
            return null;
        }
        return mactchData;
    }

    private static StockDayData getNextMinuteStockDayData(StockDayData data, List<StockDayData> stockDayDataList) {
        int index = 0;
        for (int i = 0; i < stockDayDataList.size(); i++) {
            StockDayData tempData = stockDayDataList.get(i);
            if (tempData.getDatetime().equals(data.getDatetime())) {
                index = i;
                break;
            }
        }
        if (index == stockDayDataList.size() - 1) {
            return stockDayDataList.get(stockDayDataList.size() - 1);
        }
        return stockDayDataList.get(index + 1);
    }

    /**
     * 获取macd顶背离的卖点
     *
     * @param fenshiList
     * @param beforeClosePrice
     * @return
     */
    public static StockDayData getDivergeData(List<StockDayData> fenshiList, BigDecimal beforeClosePrice) {
        if (CollectionUtils.isEmpty(fenshiList) || fenshiList.size() < 30) {
            return null;
        }
        MacdRegion maxUpMacdRegion = getMaxUpMacdRegion(fenshiList, beforeClosePrice);
        if (Objects.isNull(maxUpMacdRegion)) {
            return null;
        }
        //找到最高价以后衰弱的macd
        MacdData macdData = Macd.getMacdDataAfterMax(maxUpMacdRegion, beforeClosePrice);
        if (Objects.isNull(macdData)) {
            return null;
        }
        //忽略掉收益低于5个点或者高于9个点的票
        BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(macdData.getPrice(), beforeClosePrice);
        if (BigDecimalUtils.isLt(rate, BigDecimalUtils.five)) {
            return null;
        }
        if (BigDecimalUtils.isGt(rate, BigDecimalUtils.nine)) {
            return null;
        }
        String sellTimeStr = macdData.getDatetime();
        Date sellTime = DateUtil.parseDateTime(sellTimeStr);
        return fenshiList.stream().filter(data -> DateUtil.parseDateTime(data.getDatetime()).after(sellTime))
            .findFirst().orElse(null);
    }

    /**
     * 获取macd最大值的波段区间
     *
     * @param fenshiList
     * @param beforeClosePrice
     * @return
     */
    private static MacdRegion getMaxUpMacdRegion(List<StockDayData> fenshiList, BigDecimal beforeClosePrice) {
        List<MacdRegion> macdRegionList = Macd.getFenshiMacdRegionList(fenshiList);
        if (CollectionUtils.isEmpty(macdRegionList) && macdRegionList.size() == 1) {
            return null;
        }
        macdRegionList = macdRegionList.stream().filter(t -> BooleanUtils.isTrue(t.getUpFlag())).collect(
            Collectors.toList());
        MacdRegion maxMacdRegion = macdRegionList.stream().max(Comparator.comparing(MacdRegion::getRegionValue)).orElse(
            null);
        if (Objects.isNull(maxMacdRegion) || CollectionUtils.isEmpty(maxMacdRegion.getDataList())) {
            return null;
        }

        BigDecimal maxRegionPrice = maxMacdRegion.getBegin().getPrice();
        for (MacdData macdData : maxMacdRegion.getDataList()) {
            if (BigDecimalUtils.isGt(macdData.getPrice(), maxRegionPrice)) {
                maxRegionPrice = macdData.getPrice();
            }
        }
        Date maxTime = DateUtil.parseDateTime(maxMacdRegion.getLimit().getDatetime());
        String twoHourTime = fenshiList.get(0).getDate() + " 14:00:00";
        String tenHourTime = fenshiList.get(0).getDate() + " 10:00:00";

        for (MacdRegion macdRegion : macdRegionList) {
            //信号在10点以前忽略
            if (DateUtils.beforeOrEquals(macdRegion.getBegin().getDatetime(), tenHourTime)) {
                continue;
            }
            //信号在2点以后忽略,后面1小时亏不了多少
            if (DateUtils.afterOrEquals(macdRegion.getBegin().getDatetime(), twoHourTime)) {
                continue;
            }
            Date time = DateUtil.parseDateTime(macdRegion.getLimit().getDatetime());
            //最大macd区间以后,存在高于该区间的macd区间
            if (time.after(maxTime)) {
                BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(macdRegion.getLimit().getPrice(),
                    maxRegionPrice);
                BigDecimal openRate = BigDecimalUtils.subStractAndDividePrecent(macdRegion.getLimit().getPrice(),
                    fenshiList.get(0).getOpenPrice());
                BigDecimal beforeCloseRate = BigDecimalUtils.subStractAndDividePrecent(macdRegion.getLimit().getPrice(),
                    beforeClosePrice);
                //卖出价高于最大macd区间且比开盘价高于5%
                if (BigDecimalUtils.isGt(rate, BigDecimal.ONE) && BigDecimalUtils.isGt(openRate, BigDecimalUtils.five)
                    && BigDecimalUtils.isGt(beforeCloseRate, BigDecimalUtils.five)) {
                    return macdRegion;
                }
            }
        }
        return null;
    }

    /**
     * 计算分时压力卖出位
     *
     * @param fenshiList
     * @param beforeClosePrice
     * @return
     */
    public static StockDayData getAveragePressData(List<StockDayData> fenshiList, BigDecimal beforeClosePrice) {
        if (CollectionUtils.isEmpty(fenshiList) || fenshiList.size() < 10) {
            return null;
        }
        boolean lowFlag = false;
        boolean beforeLowFlag = false;
        boolean firstUpFlag = true;
        BigDecimal firstUpBeforeMinPrice = new BigDecimal(1000000);
        int crossCount = 0;
        int crossInterval = 0;
        StockDayData matchData = null;
        int highCount = 0;
        int lowCount = 0;
        for (int i = 2; i < fenshiList.size(); i++) {
            StockDayData data = fenshiList.get(i);
            BigDecimal range = BigDecimalUtils.subtract(data.getAvgPrice(), data.getClosePrice());
            //压力位定义为收盘价小于平均价且平均价与分时价差大于1分钱
            lowFlag = BigDecimalUtils.isLt(data.getClosePrice(), data.getAvgPrice()) && BigDecimalUtils.isGt(range,
                BigDecimalUtils.zeroPointZeroOne);
            if (lowFlag) {
                lowCount++;
            } else {
                highCount++;
            }
            if (!lowFlag) {
                //上穿
                if (beforeLowFlag) {
                    crossCount++;
                }
                crossInterval++;
                if (firstUpFlag) {
                    firstUpFlag = false;
                    firstUpBeforeMinPrice = data.getMinPrice();
                }
            }
            //下穿
            if (lowFlag && !beforeLowFlag) {
                //上穿下穿间隔小于2分钟,不设为上穿
                if (crossInterval > 0 && crossInterval <= 2 && crossCount > 0) {
                    crossCount--;
                }
                crossInterval = 0;
            }
            beforeLowFlag = lowFlag;
            //第三次上穿为卖出位
            if (crossCount >= 3) {
                matchData = data;
                break;
            }
        }
        if (crossCount >= 3) {
            //第一次上穿前从开盘价跌落2个点以上，且第三次上穿时股价位于均线上方时间小于下方，则认为为压力卖出位
            BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(fenshiList.get(0).getOpenPrice(),
                firstUpBeforeMinPrice);
            BigDecimal beforeCloseRate = BigDecimalUtils.subStractAndDividePrecent(beforeClosePrice,
                firstUpBeforeMinPrice);
            BigDecimal highRate = BigDecimalUtils.divide(new BigDecimal(highCount), new BigDecimal(lowCount));
            if (BigDecimalUtils.isGe(rate, BigDecimalUtils.two)
                && BigDecimalUtils.isGe(beforeCloseRate, BigDecimalUtils.three)
                && BigDecimalUtils.isLt(highRate, BigDecimalUtils.zeroPointSix)) {
                return matchData;
            }
        }
        return null;
    }

    /**
     * 计算分时反弹低于开盘价卖出位
     *
     * @param fenshiList
     * @param beforeClosePrice
     * @return
     */
    public static StockDayData getAverageReverseLtOpenPriceData(List<StockDayData> fenshiList,
        BigDecimal beforeClosePrice) {
        if (CollectionUtils.isEmpty(fenshiList) || fenshiList.size() < 10) {
            return null;
        }
        BigDecimal openPrice = fenshiList.get(0).getOpenPrice();
        boolean lowFlag = false;
        boolean beforeLowFlag = false;
        boolean firstUpFlag = true;
        //第一次上穿均线的最低价
        BigDecimal firstUpBeforeMinPrice = new BigDecimal(1000000);
        int crossCount = 0;
        int crossInterval = 0;
        StockDayData crossData = null;
        int highCount = 0;
        int lowCount = 0;
        String validDatetime = fenshiList.get(0).getDate() + " 10:00:00";
        //前3分钟无意义，从3分钟后开始算
        for (int i = 3; i < fenshiList.size(); i++) {
            StockDayData data = fenshiList.get(i);
            //收盘价小于平均价
            lowFlag = BigDecimalUtils.isLt(data.getClosePrice(), data.getAvgPrice());
            if (lowFlag) {
                lowCount++;
            } else {
                highCount++;
            }
            if (!lowFlag) {
                if (DateUtils.afterOrEquals(data.getDatetime(), validDatetime)) {
                    //上穿
                    if (beforeLowFlag) {
                        crossCount++;
                    }
                    crossInterval++;
                    if (firstUpFlag) {
                        firstUpFlag = false;
                        firstUpBeforeMinPrice = data.getMinPrice();
                    }
                }
            }
            //下穿
            if (lowFlag && !beforeLowFlag) {
                //上穿下穿间隔小于2分钟,不设为上穿
                if (crossInterval > 0 && crossInterval <= 2 && crossCount > 0) {
                    crossCount--;
                }
                crossInterval = 0;
            }
            beforeLowFlag = lowFlag;
            //获取第一次上穿数据,且上穿保持3分钟以上的数据
            if (crossCount >= 1 && crossInterval > 3) {
                crossData = data;
                break;
            }
        }
        //无上穿数据
        if (Objects.isNull(crossData)) {
            return null;
        }
        //在均线上时间小于在下方时间
        BigDecimal highRate = BigDecimalUtils.divide(new BigDecimal(highCount), new BigDecimal(lowCount));
        if (BigDecimalUtils.isLt(highRate, BigDecimalUtils.zeroPointSix)) {
            return null;
        }
        //第1次上穿前从开盘价跌落2个点以上，且第1次上穿时股价最高价位于开盘价下方，则认为为压力卖出位
        BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(openPrice, firstUpBeforeMinPrice);
        BigDecimal beforeCloseRate = BigDecimalUtils.subStractAndDividePrecent(beforeClosePrice, firstUpBeforeMinPrice);
        if (BigDecimalUtils.isLt(rate, BigDecimalUtils.two) && BigDecimalUtils.isLt(beforeCloseRate,
            BigDecimalUtils.three)) {
            return null;
        }
        //通过macd找到上穿后的最高价
        List<MacdRegion> macdRegionList = Macd.getFenshiMacdRegionList(fenshiList);
        if (CollectionUtils.isEmpty(macdRegionList) && macdRegionList.size() == 1) {
            return null;
        }
        MacdRegion macdRegion = Macd.getBeforeUpMacdRegion(macdRegionList, crossData.getDatetime());
        if (Objects.isNull(macdRegion)) {
            return null;
        }
        //找到最高价以后衰弱的macd
        MacdData macdData = Macd.getMacdDataAfterMax(macdRegion, beforeClosePrice);
        if (Objects.isNull(macdData)) {
            return null;
        }
        MacdData maxMacdData = macdRegion.getLimit();
        //获取上穿时间和衰弱macd之间靠后的一个时间
        String datetime = DateUtils.afterOrEquals(crossData.getDatetime(), macdData.getDatetime())
            ? crossData.getDatetime() : macdData.getDatetime();
        //上穿以后10分钟内下穿,则认为为压力卖出位
        int afterCount = 0;
        for (int i = 10; i < fenshiList.size(); i++) {
            StockDayData data = fenshiList.get(i);
            if (DateUtils.after(data.getDatetime(), datetime)) {
                afterCount++;
                if (afterCount < 10 & BigDecimalUtils.isLt(data.getClosePrice(), data.getAvgPrice())) {
                    datetime = data.getDatetime();
                }
                break;
            }
        }
        //开盘10分钟到区间存在超过开盘的数据，忽略
        for (int i = 10; i < fenshiList.size(); i++) {
            StockDayData data = fenshiList.get(i);
            if (DateUtils.beforeOrEquals(data.getDatetime(), datetime) && BigDecimalUtils.isGe(data.getClosePrice(),
                data.getOpenPrice())) {
                return null;
            }
        }
        //区间最高价小于开盘价，返回确认衰减的分时数据
        if (BigDecimalUtils.isLe(maxMacdData.getPrice(), openPrice)) {
            String finalDatetime = datetime;
            return fenshiList.stream().filter(data -> StringUtils.equals(data.getDatetime(), finalDatetime)).findFirst()
                .orElse(null);
        }
        return null;
    }

    /**
     * 到固定止损位止损
     *
     * @param fenshiList
     * @param stopLossPrice
     * @return
     */
    public static StockDayData getStopLossData(List<StockDayData> fenshiList, BigDecimal stopLossPrice) {
        if (CollectionUtils.isEmpty(fenshiList)) {
            return null;
        }
        for (StockDayData data : fenshiList) {
            if (BigDecimalUtils.isLe(data.getClosePrice(), stopLossPrice)) {
                return data;
            }
        }
        return null;
    }
}
